package com.wn.sk.product.core.lock.impl;

import com.wn.sk.product.core.lock.RedisLock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * @author yellow Docter
 * @date 2022 -09-05
 * @desc
 *  会有问题 当前的线程释放了其他的线程的锁
 *  解决 :
 *    每个线程只能 释放自己的锁
 *   // 创建线程对象
 *     private ThreadLocal<String> tlUUid = new ThreadLocal<>();
 *
 *     ThreadLocal 可以保证同个线程 存储的数据共享
 *
 *   3个人来买?
 *  只让 一个人来买 ？ 其他 2失败 ? 这个写法是不对的？
 *  让3个人 每个人都能买到，保证数据的完整性
 *
 *
 */
@Component
public class RedisLockImpl implements RedisLock {

    @Autowired
    private RedisTemplate redisTemplate;

    //map key 是 当前线程  value 在同一线程中共享的数据

    private ThreadLocal<String> tlUUid = new ThreadLocal<>();

    @Override
    public Boolean tryLock(String key, TimeUnit unit, Long timeout) {


        //生产一个编号
        String uuid = UUID.randomUUID().toString();

        //把当前的线程 和 uuid  编号进行绑定
        tlUUid.set(uuid);

        Boolean isLock =
                redisTemplate.opsForValue().setIfAbsent(key, uuid,timeout,unit);
        return isLock;
    }

    @Override
    public void release(String key) {
        // 把当前线程中的 编号 进行判断 如果是同一线程 就可以删除 自己线程的锁
        if (tlUUid.get() .equals(redisTemplate.opsForValue().get(key))){
            redisTemplate.delete(key);

            //把前前的线程 编号进行删除
            tlUUid.remove();
        }
    }

}
